package com.itlong.cloud.controller.property;

import com.alibaba.fastjson.JSON;
import com.itlong.cloud.POJO.DTO.operate.OperateOSSCallBackDTO;
import com.itlong.cloud.POJO.DTO.property.*;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.operate.OperateOSSTokenVO;
import com.itlong.cloud.POJO.VO.property.*;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.AuthAccessRequired;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.annotation.UnAuthAccessRequired;
import com.itlong.cloud.annotation.UnParamEncrypt;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.PropertyErrorCodeEnum;
import com.itlong.cloud.equip.property.IDeviceMediaInfoServiceClient;
import com.itlong.cloud.equip.property.IPropertyEquipServiceClient;
import com.itlong.cloud.iottp.IIotAliOSSServiceClient;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.RandomUtil;
import com.itlong.cloud.utils.words.NumberHandlerUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.IStreamCoder;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <desc>
 *      设备多媒体信息管理控制器
 * </desc>
 *
 * @createDate 2017-10-24
 */
@RestController
@RequestMapping("equip/deviceMediaInfo")
@RefreshScope
public class DeviceMediaInfoController extends BaseController {

    private static final Logger LOG = LoggerFactory.getLogger(DeviceMediaInfoController.class);


    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;

    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;

    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;

    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;

    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;




    @Autowired
    IDeviceMediaInfoServiceClient iDeviceMediaInfoServiceClient;  //设备多媒体信息服务接口协议提供对象.

    @Autowired
    IPropertyEquipServiceClient iPropertyEquipServiceClient; //获取门口机和围墙机提供者接口

    @Autowired
    IIotAliOSSServiceClient iIotAliOSSServiceClient;

    /**
     * <desc>
     *     一键启用/禁用设备多媒体信息【根据多媒体Id列表】
     * </desc>
     * @param  deviceMediaSetEnableDTO  一键启用/禁用多媒体信息参数对象
     * @return MessageVO 标准格式化响应结果
     * @author LewisLouis
     * @createDate 2017-10-24
     */
    @LoggerInfo(operateDesc = LogDescConstant.DEVICE_MEDIA_SETENABLE_LOG_DESC)
    @RequestMapping(path = "/setEnable", method = RequestMethod.POST)
    @ResponseBody
    @AuthAccessRequired
    public Object setMediaInfoEnable(DeviceMediaSetEnableDTO deviceMediaSetEnableDTO) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            deviceMediaSetEnableDTO = HttpProtocolUtil.parseRequestParamToDTO(DeviceMediaSetEnableDTO.class, request);
            if (null == deviceMediaSetEnableDTO){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //多媒体Id字符串不能为空
            if (StringUtils.isBlank(deviceMediaSetEnableDTO.getMediaIds())) {
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIAID_NOT_NULL.getErrorCode());
            }
            //禁用选中的设备多媒体信息
            iDeviceMediaInfoServiceClient.setMediaInfoEnable(deviceMediaSetEnableDTO);
            return new MessageVO(deviceMediaSetEnableDTO.getMediaIds(),BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }
        catch (Exception e){
            throw new DataAccessException("【物业_多媒体_多媒体信息】启用/禁用多媒体信息失败", e);
        }
    }

    /**
     * <desc>
     *      分页查询设备多媒体信息
     * </desc>
     *
     * @param deviceMediaInfoGetPageDTO 分页查询设备多媒体信息数据传输对象
     * @return MessageVO 标准格式化响应结果（含分页查询结果对象）
     * @author Lix
     * @createDate 2017-10-24
     */
    @RequestMapping(path = "getPage", method = RequestMethod.POST)
    @ResponseBody
    @AuthAccessRequired
    public Object getMediaInfoByPage(DeviceMediaInfoGetPageDTO deviceMediaInfoGetPageDTO) {
        MessageVO messageVO;
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            deviceMediaInfoGetPageDTO = HttpProtocolUtil.parseRequestParamToDTO(DeviceMediaInfoGetPageDTO.class, request);
            //判断参数合法性
            if (null == deviceMediaInfoGetPageDTO) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (StringUtils.isNotBlank(deviceMediaInfoGetPageDTO.getPutStartTime()) && StringUtils.isNotBlank(deviceMediaInfoGetPageDTO.getPutEndTime())) {
                Date putStartTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(deviceMediaInfoGetPageDTO.getPutStartTime());
                Date putEndTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(deviceMediaInfoGetPageDTO.getPutEndTime());
                // 投放开始时间必须小于投放结束时间
                if (!(putStartTime.compareTo(putEndTime) < 0)) {
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_INFO_PUT_TIME_AVAILABLE_ERR.getErrorCode());
                }
            }
            if (StringUtils.isNotBlank(deviceMediaInfoGetPageDTO.getCreateStartTime()) && StringUtils.isNotBlank(deviceMediaInfoGetPageDTO.getCreateEndTime())) {
                Date createStartTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(deviceMediaInfoGetPageDTO.getCreateStartTime());
                Date createEndTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(deviceMediaInfoGetPageDTO.getCreateEndTime());
                // 创建开始时间必须小于创建结束时间
                if (!(createStartTime.compareTo(createEndTime) < 0)) {
                    return new MessageVO(PropertyErrorCodeEnum.MEDIA_INFO_SEARCH_CREATE_TIME_AVAILABLE_ERR.getErrorCode());
                }
            }
            Page<DeviceMediaInfoVO> page = iDeviceMediaInfoServiceClient.getMediaInfoByPage(deviceMediaInfoGetPageDTO);
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), page);
        } catch (Exception e) {
            throw new DataAccessException("【物业_多媒体_多媒体信息】分页查询多媒体信息失败", e);
        }
        return messageVO;
    }





    /**
     * <desc>
     *    Ftp上传文件，返回Url.
     * </desc>
     *
     * @param inputStream 文件流
     * @return 文件上传成功后会返回Url,否则返回空
     * @author LewisLouis
     * @createDate 2017-11-20
     */
    public String uploadFile(InputStream inputStream, String fileName) throws IOException {

        String fileUrl = "";
        String fileType = StringHandlerUtil.copySubStr(fileName, fileName.lastIndexOf('.'), fileName.length());
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                inputStream,
                fileType,
                FILE_ACCESS_URL,
                FileCatalogEnum.MULTIMEDIA_FILE.getType()
        );
        Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
        Boolean returnCode = (Boolean)resultMap.get("returnCode");
        if (returnCode == false){
            return fileUrl;
        }
        fileUrl = resultMap.get("accessPath").toString();
        return fileUrl;
    }


    /**
     * <desc>
     *    根据文件MD5校验值在附件列表中查找附件.
     * </desc>
     *
     * @param md5 文件MD5校验值
     * @param attacheFiles 附件信息列表
     * @return 查找到的附件信息
     * @author LewisLouis
     * @createDate 2017-11-23
     */
    public DeviceMediaAttacheFileInfoVO getAttacheFileInfoByMD5(String md5, List<DeviceMediaAttacheFileInfoVO> attacheFiles){
        for (DeviceMediaAttacheFileInfoVO deviceMediaAttacheFileInfoVO:attacheFiles){
            if (StringHandlerUtil.compareStrWithOutEmpty(md5,deviceMediaAttacheFileInfoVO.getFileMd5())){
                return  deviceMediaAttacheFileInfoVO;
            }
        }
        return  null;
    }

    /**
    * <desc>
    *    拷贝流.
    * </desc>
    *
    * @param  inputStream 输入流
    * @return 拷贝后的输出流
    * @author LewisLouis
    * @createDate 2017-11-23
    */
    public static ByteArrayOutputStream cloneInputStream (InputStream inputStream) throws IOException {
            ByteArrayOutputStream forCloneStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int readLength = 0;
            while ((readLength = inputStream.read(buffer)) != -1) {
                forCloneStream.write(buffer, 0, readLength);
            }
            forCloneStream.flush();
            return forCloneStream;
            // InputStream sourceStream = new ByteArrayInputStream(outputStream.toByteArray());
            //InputStream cloneStream = new ByteArrayInputStream(outputStream.toByteArray());
    }

    /**
     * <desc>
     *     分页查询项目下所有的门口机设备和围墙机设备
     * </desc>
     *
     * @param propertyIntercomGetByProjectIdDTO 依靠projectId查询该项目下所有云对讲设备数据传输对象
     * @return MessageVo 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/3/26
     */
    @PostMapping(path = "getIntercomList")
    @ResponseBody
    public Object getAllEquipsByProjectId(PropertyIntercomGetByProjectIdDTO propertyIntercomGetByProjectIdDTO){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyIntercomGetByProjectIdDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyIntercomGetByProjectIdDTO.class, request);
            if (propertyIntercomGetByProjectIdDTO == null){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (propertyIntercomGetByProjectIdDTO.getProjectId() == null
                    || "".equals(propertyIntercomGetByProjectIdDTO.getProjectId())){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            // 需求改动需要返回分页结果
            Page<PropertyAllEquipGetVO> page = iPropertyEquipServiceClient.getAllEquipsByProjectId(propertyIntercomGetByProjectIdDTO);
//            List<PropertyAllEquipGetVO> propertyEquipGetVOList = iPropertyEquipServiceClient.getAllEquipsByProjectId(propertyIntercomGetByProjectIdDTO);
//            Map<String,Object> propertyEquipGetVOMap = new HashMap<>();
//            propertyEquipGetVOMap.put("propertyEquipGetVOList",propertyEquipGetVOList);
//            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),propertyEquipGetVOMap);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),page);
        } catch (Exception e) {
            throw new DataAccessException("【物业_系统_多媒体资源管理】获取门口机、围墙机设备失败", e);
        }
    }

    /**
     * <desc>
     *     分页查询项目下或多媒体资源所绑定的所有支持平板人脸识别的设备
     * </desc>
     *
     * @param propertyPadFaceRecognitionGetForMediaDTO 使用projectId或mediaId查询该项目下所有支持人脸识别的云电梯或门禁设备数据传输对象
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/05/10
     */
    @PostMapping(path = "getPadFaceEquipByPage")
    @ResponseBody
    public Object getPadFaceEquipByPage(PropertyPadFaceRecognitionGetForMediaDTO propertyPadFaceRecognitionGetForMediaDTO){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyPadFaceRecognitionGetForMediaDTO = HttpProtocolUtil.parseRequestParamToDTO(PropertyPadFaceRecognitionGetForMediaDTO.class, request);
            if (propertyPadFaceRecognitionGetForMediaDTO == null){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (StringUtils.isBlank(propertyPadFaceRecognitionGetForMediaDTO.getProjectId())){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            Page<PropertyPadFaceEquipVO> page = iPropertyEquipServiceClient.getPadFaceEquipByPage(propertyPadFaceRecognitionGetForMediaDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),page);
        } catch (Exception e) {
            throw new DataAccessException("【物业_系统_多媒体资源管理】获取多媒体资源所绑定的所有支持平板人脸识别的设备失败", e);
        }
    }

    /**
     * <desc>
     *      获取阿里OSS通行证
     * <desc/>
     *
     * @return
     * @author wangzhi
     * @createDate 2018/11/22
     */
    @RequestMapping(value = "/getOSSToken", method = RequestMethod.POST)
    @ResponseBody
    public Object getOSSToken(){
        MessageVO messageVO;
        try{
            StringBuffer fileName = new StringBuffer();
            fileName.append(DateFormatUtils.format(new Date(), DateUtil.YYMMDDHHMMSS)).
                    append(RandomUtil.getRandomStringByLength(8)).append(".mp4");
            OperateOSSTokenVO operateOSSTokenVO = iIotAliOSSServiceClient.getMediaOSSToken();
            operateOSSTokenVO.setUploadFileName(fileName.toString());
            messageVO=new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), operateOSSTokenVO);
        }catch (Exception e){
            throw new DataAccessException("【获取阿里OSS通行证getOSSTokenk】获取阿里OSS通行证失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      阿里OSS回调入口
     * <desc/>
     *
     * @return
     * @author Qiang.S
     * @createDate 2018-07-12
     */
    @RequestMapping(value = "/OSSCallBack", method = RequestMethod.POST)
    @UnAuthAccessRequired
    @ResponseBody
    @UnParamEncrypt
    public void OSSCallBack(HttpServletRequest request, HttpServletResponse response){
        try {
            //LOG.info("多媒体资源上传视频阿里OSS回调入口：" + request.getHeaderNames());
            OperateOSSCallBackDTO operateOSSCallBackDTO = new OperateOSSCallBackDTO();
            operateOSSCallBackDTO.setAutorizationInput(new String(request.getHeader("Authorization")));
            operateOSSCallBackDTO.setContentLen(Integer.parseInt(request.getHeader("content-length")));
            operateOSSCallBackDTO.setOssCallbackBody(GetPostBody(request.getInputStream(), Integer.parseInt(request.getHeader("content-length"))));
            operateOSSCallBackDTO.setPubKeyInput(request.getHeader("x-oss-pub-key-url"));
            operateOSSCallBackDTO.setQueryString(request.getQueryString());
            operateOSSCallBackDTO.setUri(request.getRequestURI());
            //LOG.info("阿里OSS回调参数：" + operateOSSCallBackDTO);
            operateOSSCallBackDTO.setSystemType(SystemTypeEnum.PROPERTY.getType());
            boolean ref = iIotAliOSSServiceClient.OSSMediaCallBack(operateOSSCallBackDTO);
            if (ref) {
                response(request, response, "{\"Status\":\"OK\"}", HttpServletResponse.SC_OK);
            }else {
                response(request, response, "{\"Status\":\"verdify not ok\"}", HttpServletResponse.SC_BAD_REQUEST);
            }
        }catch (Exception e){
            try {
                response(request, response, "{\"Status\":\"verdify not ok\"}", HttpServletResponse.SC_BAD_REQUEST);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            throw new DataAccessException("【阿里OSS回调OSSCallBack】阿里OSS回调处理失败", e);
        }
    }

    /**
     * <desc>
     *     组装阿里OSS回调response
     * </desc>
     *
     * @return
     * @author Qiang.S
     * @createDate 2018/07/12
     */
    private void response(HttpServletRequest request, HttpServletResponse response, String results, int status) throws IOException {
        String callbackFunName = request.getParameter("callback");
        response.addHeader("Content-Length", String.valueOf(results.length()));
        if (callbackFunName == null || callbackFunName.equalsIgnoreCase("")){
            response.getWriter().println(results);
        }
        else{
            response.getWriter().println(callbackFunName + "( " + results + " )");
        }
        response.setStatus(status);
        response.flushBuffer();
    }

    /**
     * <desc>
     *     获取阿里OSS中GetPostBody
     * </desc>
     *
     * @return
     * @author Qiang.S
     * @createDate 2018/07/11
     */
    private String GetPostBody(InputStream is, int contentLen) {
        if (contentLen > 0) {
            int readLen = 0;
            int readLengthThisTime = 0;
            byte[] message = new byte[contentLen];
            try {
                while (readLen != contentLen) {
                    readLengthThisTime = is.read(message, readLen, contentLen - readLen);
                    if (readLengthThisTime == -1) {// Should not happen.
                        break;
                    }
                    readLen += readLengthThisTime;
                }
                return new String(message);
            } catch (IOException e) {
            }
        }
        return "";
    }

    /**
     * <desc>
     *     保存多媒体信息
     * </desc>
     *
     * @param deviceMediaInfoSaveForBrowserDTO 保存多媒体信息数据传输对象
     * @param httpServletRequest
     * @return MessageVo 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/3/26
     */
    @LoggerInfo(operateDesc = LogDescConstant.DEVICE_MEDIA_INFO_SAVE_LOG_DESC)
    @PostMapping(path = "saveMediaInfo")
    @ResponseBody
    @AuthAccessRequired
    public Object saveDeviceMediaInfo(DeviceMediaInfoSaveForBrowserDTO deviceMediaInfoSaveForBrowserDTO,
                                         HttpServletRequest httpServletRequest){
        try {
            deviceMediaInfoSaveForBrowserDTO = HttpProtocolUtil.parseRequestParamToDTO(DeviceMediaInfoSaveForBrowserDTO.class, httpServletRequest);
            //判断参数合法性
            if (null == deviceMediaInfoSaveForBrowserDTO){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }

            // 多媒体资源设备类型不能为空
            if (!NumberHandlerUtil.isEqual(deviceMediaInfoSaveForBrowserDTO.getEquipType(),PropertyEquipTypeEnum.PAD_FACE_RECOGNITION.getType()) &&
                    !NumberHandlerUtil.isEqual(deviceMediaInfoSaveForBrowserDTO.getEquipType(),PropertyEquipTypeEnum.CLOUD_INTERCOM.getType()) &&
                    !NumberHandlerUtil.isEqual(deviceMediaInfoSaveForBrowserDTO.getEquipType(),PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType())){
                return new MessageVO(PropertyErrorCodeEnum.MEDIA_EQUIP_TYPE_EMPTY_ERR.getErrorCode());
            }

            // 多媒体资源设备类型若为平板人脸识别，则平板人脸识别类别不能为空
            if (NumberHandlerUtil.isEqual(deviceMediaInfoSaveForBrowserDTO.getEquipType(),PropertyEquipTypeEnum.PAD_FACE_RECOGNITION.getType()) &&
                    (!NumberHandlerUtil.isEqual(deviceMediaInfoSaveForBrowserDTO.getChildrenType(),PropertyEquipTypeEnum.ENTRANCE.getType()) &&
                    !NumberHandlerUtil.isEqual(deviceMediaInfoSaveForBrowserDTO.getChildrenType(),PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType()))){
                return new MessageVO(PropertyErrorCodeEnum.MEDIA_CHILDREN_TYPE_EMPTY_ERR.getErrorCode());
            }

            //多媒体标题合法性
            if (StringUtils.isBlank(deviceMediaInfoSaveForBrowserDTO.getTitle())){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_TITLE_NOT_EMPTY_ERR.getErrorCode());
            }
            if (deviceMediaInfoSaveForBrowserDTO.getTitle().length() > PlatformConstants.MEDIA_TITLE_MAX_LENGTH){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_TITLE_TOO_LONG_ERR.getErrorCode());
            }

            // 多媒体资源绑定设备列表或地址列表不能为空
            if (StringUtils.isBlank(deviceMediaInfoSaveForBrowserDTO.getBindInfos())){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_INFO_BIND_EMPTY_ERR.getErrorCode());
            }

            // 设备类型为平板人脸识别是多媒体类型只能为图片
            if (NumberHandlerUtil.isEqual(deviceMediaInfoSaveForBrowserDTO.getEquipType(),PropertyEquipTypeEnum.PAD_FACE_RECOGNITION.getType()) &&
                    !NumberHandlerUtil.isEqual(deviceMediaInfoSaveForBrowserDTO.getType(),MediaTypeEnum.IMGAE.getType())){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_SORT_INVALID_ERR.getErrorCode());
            }

            // 多媒体资源类型的合法性，1-3之间
            Integer mediaType = deviceMediaInfoSaveForBrowserDTO.getType();
            if (!NumberHandlerUtil.isInRange(mediaType, MediaTypeEnum.TEXT.getType(),MediaTypeEnum.VIDEO.getType())){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_SORT_INVALID_ERR.getErrorCode());
            }

            // 多媒体资源投放时间区间的合法性
            if (!(StringUtils.isNotBlank(deviceMediaInfoSaveForBrowserDTO.getPutStartTime())&&
                    StringUtils.isNotBlank(deviceMediaInfoSaveForBrowserDTO.getPutEndTime()))){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_INFO_PUT_TIME_EMPTY_ERR.getErrorCode());
            }
            Date putStartTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(deviceMediaInfoSaveForBrowserDTO.getPutStartTime());
            Date putEndTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(deviceMediaInfoSaveForBrowserDTO.getPutEndTime());
            // 投放开始时间必须小于投放结束时间
            if (!(putStartTime.compareTo(putEndTime) < 0)){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_INFO_PUT_TIME_AVAILABLE_ERR.getErrorCode());
            }

            //将页面传入的多媒体资源数据部分属性转换为内部对象属性
            DeviceMediaInfoSaveDTO deviceMediaInfoSaveDTO = new DeviceMediaInfoSaveDTO();
            BeanUtils.copyProperties(deviceMediaInfoSaveForBrowserDTO,deviceMediaInfoSaveDTO);
            //分析多媒体资源绑定的地址和设备列表
            if (StringUtils.isNotBlank(deviceMediaInfoSaveForBrowserDTO.getBindInfos())){
                List<DeviceMediaBindDTO> deviceMediaBindDTOS = null;
                List<DeviceMediaBindAddressDTO> deviceMediaBindAddressDTOList = new ArrayList<>();
                List<DeviceMediaBindDeviceDTO> deviceMediaBindDeviceDTOS = new ArrayList<>();
                List<DeviceMediaBindPadFaceDTO> deviceMediaBindPadFaceDTOS = new ArrayList<>();
                List<DeviceMediaBindPadFaceDTO> deviceMediaBindEntranceDTOS = new ArrayList<>();
                try {
                    deviceMediaBindDTOS = JSON.parseArray(deviceMediaInfoSaveForBrowserDTO.getBindInfos(),
                            DeviceMediaBindDTO.class);
                } catch (Exception e) {
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_BIND_INVALID_ERR.getErrorCode());
                }
                // 遍历解析得到的绑定地址和设备列表
                for (DeviceMediaBindDTO deviceMediaBindDTO:deviceMediaBindDTOS) {
                    // 根据smartType属性判断是门口机还是围墙机
                    if (NumberHandlerUtil.isEqual(deviceMediaBindDTO.getSmartType(),31)){
                        DeviceMediaBindAddressDTO deviceMediaBindAddressDTO = new DeviceMediaBindAddressDTO();
                        deviceMediaBindAddressDTO.setDeviceUnique(deviceMediaBindDTO.getDeviceUnique());
                        deviceMediaBindAddressDTOList.add(deviceMediaBindAddressDTO);
                    }else if (NumberHandlerUtil.isEqual(deviceMediaBindDTO.getSmartType(),32)){
                        DeviceMediaBindDeviceDTO deviceMediaBindDeviceDTO = new DeviceMediaBindDeviceDTO();
                        deviceMediaBindDeviceDTO.setDeviceUnique(deviceMediaBindDTO.getDeviceUnique());
                        deviceMediaBindDeviceDTO.setSn(deviceMediaBindDTO.getSn());
                        deviceMediaBindDeviceDTOS.add(deviceMediaBindDeviceDTO);
                    }else if (NumberHandlerUtil.isEqual(deviceMediaBindDTO.getSmartType(),24)){//一体式人脸识别门禁
                        DeviceMediaBindPadFaceDTO deviceMediaBindDeviceDTO = new DeviceMediaBindPadFaceDTO();
                        deviceMediaBindDeviceDTO.setDeviceUnique(deviceMediaBindDTO.getDeviceUnique());
                        deviceMediaBindEntranceDTOS.add(deviceMediaBindDeviceDTO);
                    } else {
                        DeviceMediaBindPadFaceDTO deviceMediaBindPadFaceDTO = new DeviceMediaBindPadFaceDTO();
                        deviceMediaBindPadFaceDTO.setDeviceUnique(deviceMediaBindDTO.getDeviceUnique());
                        deviceMediaBindPadFaceDTOS.add(deviceMediaBindPadFaceDTO);
                    }
                }
                if (null != deviceMediaBindAddressDTOList && !deviceMediaBindAddressDTOList.isEmpty()){
                    deviceMediaInfoSaveDTO.setBindAddressInfo(deviceMediaBindAddressDTOList);
                }
                if (null != deviceMediaBindDeviceDTOS && !deviceMediaBindDeviceDTOS.isEmpty()){
                    deviceMediaInfoSaveDTO.setBindDeviceInfo(deviceMediaBindDeviceDTOS);
                }
                if (null != deviceMediaBindPadFaceDTOS && !deviceMediaBindPadFaceDTOS.isEmpty()){
                    deviceMediaInfoSaveDTO.setBindPadFaceInfo(deviceMediaBindPadFaceDTOS);
                }
                if (null != deviceMediaBindEntranceDTOS && !deviceMediaBindEntranceDTOS.isEmpty()){
                    deviceMediaInfoSaveDTO.setBindUnibodyEntranceInfo(deviceMediaBindEntranceDTOS);
                }
            }
            // 设备类型为云对讲时两个绑定至少存在一个
            if (NumberHandlerUtil.isEqual(deviceMediaInfoSaveDTO.getEquipType(),PropertyEquipTypeEnum.CLOUD_INTERCOM.getType())) {
                if ((null == deviceMediaInfoSaveDTO.getBindAddressInfo() || deviceMediaInfoSaveDTO.getBindAddressInfo().isEmpty()) &&
                        (null == deviceMediaInfoSaveDTO.getBindDeviceInfo() || deviceMediaInfoSaveDTO.getBindDeviceInfo().isEmpty())){
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_INFO_BIND_EMPTY_ERR.getErrorCode());
                }
            // 设备类型为平板人脸识别时绑定设备不能为空
            } else if ((null == deviceMediaInfoSaveDTO.getBindPadFaceInfo() || deviceMediaInfoSaveDTO.getBindPadFaceInfo().isEmpty()) && deviceMediaInfoSaveDTO.getEquipType() != PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType()){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_INFO_BIND_EMPTY_ERR.getErrorCode());
            }

            // 存入投放时间
            deviceMediaInfoSaveDTO.setPutStartTime(putStartTime);
            deviceMediaInfoSaveDTO.setPutEndTime(putEndTime);

            // 存入发布状态
            deviceMediaInfoSaveDTO.setPublishStatus(DeviceMediaInfoPublishStatusEnum.UN_CHECKED.getType());

            //上传多媒体资源附件（图片\视频）
            if (mediaType != MediaTypeEnum.TEXT.getType()){
                boolean isMultipart = ServletFileUpload.isMultipartContent(httpServletRequest);
                if (!isMultipart) {
                    //是否是带文件上传的表单
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_RESOURCE_EMPTY_ERR.getErrorCode());
                }
                MessageVO messageVO = this.supUpLoadMediaFileForSave(httpServletRequest,deviceMediaInfoSaveDTO);
                if (null != messageVO)
                {
                    return messageVO;
                }
            }else {
                if (StringUtils.isBlank(deviceMediaInfoSaveForBrowserDTO.getContent())){
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_TEXT_NOT_EMPTY_ERR.getErrorCode());
                }
                if (deviceMediaInfoSaveDTO.getContent().length() > PlatformConstants.MEDIA_TEXT_MAX_LENGTH){
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_TEXT_TOO_LONG_ERR.getErrorCode());
                }
            }
            //添加单个多媒体资源信息
            iDeviceMediaInfoServiceClient.saveDeviceMediaInfo(deviceMediaInfoSaveDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【物业_系统_多媒体资源管理】添加多媒体资源失败", e);
        }
    }

    /**
     * <desc>
     *     精确查询，获取单个设备多媒体信息【根据多媒体Id（mediaId）】
     * </desc>
     *
     * @param mediaId 多媒体id
     * @return 单个设备多媒体信息结果对象
     * @author wangzhi
     * @createDate 2018-03-28
     */
    @PostMapping(path = "getOneMediaInfo")
    @ResponseBody
    @AuthAccessRequired
    public Object getOneMediaInfo(String mediaId){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            mediaId = request.getAttribute("mediaId") == null ? null : request.getAttribute("mediaId").toString();
            //多媒体Id不能为空
            if (StringUtils.isBlank(mediaId)){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIAID_NOT_NULL.getErrorCode());
            }
            //查询单个设备多媒体信息
            DeviceMediaInfoGetVO deviceMediaInfoVO = iDeviceMediaInfoServiceClient.getOneMediaInfo(mediaId);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),deviceMediaInfoVO);
        } catch (Exception e) {
            throw new DataAccessException("【物业_多媒体_多媒体信息】精确查询单个多媒体信息失败", e);
        }
    }

    /**
     * <desc>
     *     修改多媒体资源信息
     * </desc>
     *
     * @param deviceMediaInfoUpdateForBrowserDTO 修改多媒体信息数据传输对象
     * @param httpServletRequest
     * @return MessageVo 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018/3/28
     */
    @LoggerInfo(operateDesc = LogDescConstant.DEVICE_MEDIA_INFO_UPDATE_LOG_DESC)
    @PostMapping(path = "updateMediaInfo")
    @ResponseBody
    @AuthAccessRequired
    public Object updateOneDeviceMediaInfo(DeviceMediaInfoUpdateForBrowserDTO deviceMediaInfoUpdateForBrowserDTO,
                                              HttpServletRequest httpServletRequest){
        try {
            deviceMediaInfoUpdateForBrowserDTO = HttpProtocolUtil.parseRequestParamToDTO(DeviceMediaInfoUpdateForBrowserDTO.class, httpServletRequest);

            //判断参数合法性
            if (null == deviceMediaInfoUpdateForBrowserDTO){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }

            // 多媒体资源设备类型不能为空
            if (!NumberHandlerUtil.isEqual(deviceMediaInfoUpdateForBrowserDTO.getEquipType(),PropertyEquipTypeEnum.PAD_FACE_RECOGNITION.getType()) &&
                    !NumberHandlerUtil.isEqual(deviceMediaInfoUpdateForBrowserDTO.getEquipType(),PropertyEquipTypeEnum.CLOUD_INTERCOM.getType()) &&
                    !NumberHandlerUtil.isEqual(deviceMediaInfoUpdateForBrowserDTO.getEquipType(),PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType())){
                return new MessageVO(PropertyErrorCodeEnum.MEDIA_EQUIP_TYPE_EMPTY_ERR.getErrorCode());
            }

            // 多媒体资源设备类型若为平板人脸识别，则平板人脸识别类别不能为空
            if (NumberHandlerUtil.isEqual(deviceMediaInfoUpdateForBrowserDTO.getEquipType(),PropertyEquipTypeEnum.PAD_FACE_RECOGNITION.getType()) &&
                    (!NumberHandlerUtil.isEqual(deviceMediaInfoUpdateForBrowserDTO.getChildrenType(),PropertyEquipTypeEnum.ENTRANCE.getType()) &&
                            !NumberHandlerUtil.isEqual(deviceMediaInfoUpdateForBrowserDTO.getChildrenType(),PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType()))){
                return new MessageVO(PropertyErrorCodeEnum.MEDIA_CHILDREN_TYPE_EMPTY_ERR.getErrorCode());
            }

            //多媒体标题合法性
            if (StringUtils.isBlank(deviceMediaInfoUpdateForBrowserDTO.getTitle())){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_TITLE_NOT_EMPTY_ERR.getErrorCode());
            }
            if (deviceMediaInfoUpdateForBrowserDTO.getTitle().length() > PlatformConstants.MEDIA_TITLE_MAX_LENGTH){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_TITLE_TOO_LONG_ERR.getErrorCode());
            }

            // 多媒体资源绑定设备列表或地址列表不能为空
            if (StringUtils.isBlank(deviceMediaInfoUpdateForBrowserDTO.getBindInfos())){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_INFO_BIND_EMPTY_ERR.getErrorCode());
            }

            // 设备类型为平板人脸识别是多媒体类型只能为图片
            if (NumberHandlerUtil.isEqual(deviceMediaInfoUpdateForBrowserDTO.getEquipType(),PropertyEquipTypeEnum.PAD_FACE_RECOGNITION.getType()) &&
                    !NumberHandlerUtil.isEqual(deviceMediaInfoUpdateForBrowserDTO.getType(),MediaTypeEnum.IMGAE.getType())){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_SORT_INVALID_ERR.getErrorCode());
            }

            // 多媒体资源类型的合法性，1-3之间
            Integer mediaType = deviceMediaInfoUpdateForBrowserDTO.getType();
            if (!NumberHandlerUtil.isInRange(mediaType, MediaTypeEnum.TEXT.getType(),MediaTypeEnum.VIDEO.getType())){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_SORT_INVALID_ERR.getErrorCode());
            }

            // 多媒体资源投放时间区间的合法性
            if (!(StringUtils.isNotBlank(deviceMediaInfoUpdateForBrowserDTO.getPutStartTime())&&
                    StringUtils.isNotBlank(deviceMediaInfoUpdateForBrowserDTO.getPutEndTime()))){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_INFO_PUT_TIME_EMPTY_ERR.getErrorCode());
            }
            Date putStartTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(deviceMediaInfoUpdateForBrowserDTO.getPutStartTime());
            Date putEndTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(deviceMediaInfoUpdateForBrowserDTO.getPutEndTime());
            // 投放开始时间必须小于投放结束时间
            if (!(putStartTime.compareTo(putEndTime) < 0)){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_INFO_PUT_TIME_AVAILABLE_ERR.getErrorCode());
            }

            //将页面传入的多媒体资源数据部分属性转换为内部对象属性
            DeviceMediaInfoUpdateDTO deviceMediaInfoUpdateDTO = new DeviceMediaInfoUpdateDTO();
            BeanUtils.copyProperties(deviceMediaInfoUpdateForBrowserDTO,deviceMediaInfoUpdateDTO);
            //分析多媒体资源绑定的地址和设备列表
            if (StringUtils.isNotBlank(deviceMediaInfoUpdateForBrowserDTO.getBindInfos())){
                List<DeviceMediaBindDTO> deviceMediaBindDTOS = null;
                List<DeviceMediaBindAddressDTO> deviceMediaBindAddressDTOList = new ArrayList<>();
                List<DeviceMediaBindDeviceDTO> deviceMediaBindDeviceDTOS = new ArrayList<>();
                List<DeviceMediaBindPadFaceDTO> deviceMediaBindPadFaceDTOS = new ArrayList<>();
                List<DeviceMediaBindPadFaceDTO> deviceMediaBindEntranceDTOS = new ArrayList<>();
                try {
                    deviceMediaBindDTOS = JSON.parseArray(deviceMediaInfoUpdateForBrowserDTO.getBindInfos(),
                            DeviceMediaBindDTO.class);
                } catch (Exception e) {
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_BIND_INVALID_ERR.getErrorCode());
                }
                // 遍历解析得到的绑定地址和设备列表
                for (DeviceMediaBindDTO deviceMediaBindDTO:deviceMediaBindDTOS) {
                    // 根据smartType属性判断是门口机还是围墙机
                    if (NumberHandlerUtil.isEqual(deviceMediaBindDTO.getSmartType(),31)){
                        DeviceMediaBindAddressDTO deviceMediaBindAddressDTO = new DeviceMediaBindAddressDTO();
                        deviceMediaBindAddressDTO.setDeviceUnique(deviceMediaBindDTO.getDeviceUnique());
                        deviceMediaBindAddressDTOList.add(deviceMediaBindAddressDTO);
                    }else if (NumberHandlerUtil.isEqual(deviceMediaBindDTO.getSmartType(),32)){
                        DeviceMediaBindDeviceDTO deviceMediaBindDeviceDTO = new DeviceMediaBindDeviceDTO();
                        deviceMediaBindDeviceDTO.setDeviceUnique(deviceMediaBindDTO.getDeviceUnique());
                        deviceMediaBindDeviceDTO.setSn(deviceMediaBindDTO.getSn());
                        deviceMediaBindDeviceDTOS.add(deviceMediaBindDeviceDTO);
                    }else if (NumberHandlerUtil.isEqual(deviceMediaBindDTO.getSmartType(),24)){//一体式人脸识别门禁
                        DeviceMediaBindPadFaceDTO deviceMediaBindDeviceDTO = new DeviceMediaBindPadFaceDTO();
                        deviceMediaBindDeviceDTO.setDeviceUnique(deviceMediaBindDTO.getDeviceUnique());
                        deviceMediaBindEntranceDTOS.add(deviceMediaBindDeviceDTO);
                    } else {
                        DeviceMediaBindPadFaceDTO deviceMediaBindPadFaceDTO = new DeviceMediaBindPadFaceDTO();
                        deviceMediaBindPadFaceDTO.setDeviceUnique(deviceMediaBindDTO.getDeviceUnique());
                        deviceMediaBindPadFaceDTOS.add(deviceMediaBindPadFaceDTO);
                    }
                }
                if (null != deviceMediaBindAddressDTOList && !deviceMediaBindAddressDTOList.isEmpty()){
                    deviceMediaInfoUpdateDTO.setBindAddressInfo(deviceMediaBindAddressDTOList);
                }
                if (null != deviceMediaBindDeviceDTOS && !deviceMediaBindDeviceDTOS.isEmpty()){
                    deviceMediaInfoUpdateDTO.setBindDeviceInfo(deviceMediaBindDeviceDTOS);
                }
                if (null != deviceMediaBindPadFaceDTOS && !deviceMediaBindPadFaceDTOS.isEmpty()){
                    deviceMediaInfoUpdateDTO.setBindPadFaceInfo(deviceMediaBindPadFaceDTOS);
                }
                if (null != deviceMediaBindEntranceDTOS && !deviceMediaBindEntranceDTOS.isEmpty()){
                    deviceMediaInfoUpdateDTO.setBindUnibodyEntranceInfo(deviceMediaBindEntranceDTOS);
                }
            }
            // 设备类型为云对讲时两个绑定至少存在一个
            if (NumberHandlerUtil.isEqual(deviceMediaInfoUpdateDTO.getEquipType(),PropertyEquipTypeEnum.CLOUD_INTERCOM.getType())) {
                if ((null == deviceMediaInfoUpdateDTO.getBindAddressInfo() || deviceMediaInfoUpdateDTO.getBindAddressInfo().isEmpty()) &&
                        (null == deviceMediaInfoUpdateDTO.getBindDeviceInfo() || deviceMediaInfoUpdateDTO.getBindDeviceInfo().isEmpty())){
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_INFO_BIND_EMPTY_ERR.getErrorCode());
                }
                // 设备类型为平板人脸识别时绑定设备不能为空
            } else if ((null == deviceMediaInfoUpdateDTO.getBindPadFaceInfo() || deviceMediaInfoUpdateDTO.getBindPadFaceInfo().isEmpty()) && deviceMediaInfoUpdateDTO.getEquipType() != PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType()){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_INFO_BIND_EMPTY_ERR.getErrorCode());
            }

            // 存入投放时间
            deviceMediaInfoUpdateDTO.setPutStartTime(putStartTime);
            deviceMediaInfoUpdateDTO.setPutEndTime(putEndTime);

            // 存入发布状态
            deviceMediaInfoUpdateDTO.setPublishStatus(DeviceMediaInfoPublishStatusEnum.UN_CHECKED.getType());

            DeviceMediaInfoGetVO oldDeviceMediaInfoGetVO = iDeviceMediaInfoServiceClient.getOneMediaInfo(deviceMediaInfoUpdateDTO.getMediaId());
            if (null == oldDeviceMediaInfoGetVO){
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_NOT_EXISTS_ERR.getErrorCode());
            }

            //上传多媒体资源附件（图片\视频）
            if (mediaType != MediaTypeEnum.TEXT.getType()){
                boolean isMultipart = ServletFileUpload.isMultipartContent(httpServletRequest);
                if (!isMultipart) {
                    //是否是带文件上传的表单
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_RESOURCE_EMPTY_ERR.getErrorCode());
                }

                MessageVO messageVO = this.supUpLoadMediaFileForUpdate(httpServletRequest,deviceMediaInfoUpdateDTO, oldDeviceMediaInfoGetVO);
                if (null != messageVO)
                {
                    return messageVO;
                }
            }else {
                if (StringUtils.isBlank(deviceMediaInfoUpdateForBrowserDTO.getContent())){
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_TEXT_NOT_EMPTY_ERR.getErrorCode());
                }
                if (deviceMediaInfoUpdateForBrowserDTO.getContent().length() > PlatformConstants.MEDIA_TEXT_MAX_LENGTH){
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_TEXT_TOO_LONG_ERR.getErrorCode());
                }
            }

            //修改单个多媒体资源信息
            iDeviceMediaInfoServiceClient.updateDeviceMediaInfo(deviceMediaInfoUpdateDTO);

            return new MessageVO(deviceMediaInfoUpdateForBrowserDTO.getMediaId(),BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【物业_多媒体_多媒体信息】修改多媒体信息失败", e);
        }
    }

    /**
     * <desc>
     *     发布多媒体资源，支持批量
     * </desc>
     *
     * @param mediaIds 多媒体资源id字符串
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2018-04-09
     */
    @LoggerInfo(operateDesc = LogDescConstant.DEVICE_MEDIA_INFO_PUBLISH_LOG_DESC)
    @PostMapping(path = "publishMedias")
    @ResponseBody
    @AuthAccessRequired
    public Object publishMedias(String mediaIds){
        // 客户选择要发布的多媒体资源后点下发布按钮，前端控制只传过来未发布的媒体id字符串，已确认
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            mediaIds = request.getAttribute("mediaIds") == null ? null : request.getAttribute("mediaIds").toString();
            if (StringUtils.isBlank(mediaIds)){
                return new MessageVO(PropertyErrorCodeEnum.MEDIA_ID_EMPTY_ERROR.getErrorCode());
            }
            iDeviceMediaInfoServiceClient.publishMedias(mediaIds);
            return new MessageVO(mediaIds,BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【物业_物业管理_多媒体资源管理】发布多媒体资源信息失败",e);
        }
    }

    /**
     * <desc>
     *     兼容旧多媒体数据接口
     * </desc>
     *
     * @return
     * @author wangzhi
     * @createDate 2018-04-19
     */
    @RequestMapping(path = "compatibilityOldData")
    @ResponseBody
    public Object compatibilityOldData(){
        try {
            iDeviceMediaInfoServiceClient.compatibilityOldMediaData();
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
           throw new DataAccessException("【兼容旧多媒体数据失败】",e);
        }
    }

    /**
     * <desc>
     *     修复本人因失误造成的错误数据，同时兼容旧多媒体资源的发布状态
     * </desc>
     *
     * @return
     * @author wangzhi
     * @createDate 2018-04-20
     */
    @RequestMapping(path = "repairWrongData")
    @ResponseBody
    public Object repairWrongData(){
        try {
            iDeviceMediaInfoServiceClient.repairWrongData();
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【修复错误数据失败】",e);
        }
    }



    /**
     * <desc>
     *     上传多媒体资源到Http服务器.
     * </desc>
     *
     * @param httpServletRequest
     * @param deviceMediaInfoSaveDTO
     * @return
     * @throws IOException
     * @author copy by wangzhi
     */
    private MessageVO supUpLoadMediaFileForSave(HttpServletRequest httpServletRequest, DeviceMediaInfoSaveDTO deviceMediaInfoSaveDTO) throws IOException {
        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) httpServletRequest;
        StringBuffer attacheFileUrls = new StringBuffer();
        StringBuffer attacheFiles = new StringBuffer();
        StringBuffer attacheFileMd5s = new StringBuffer();
        Map<String,MultipartFile> multipartFileMap = multipartRequest.getFileMap();
        if (multipartFileMap.isEmpty()){
            return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_RESOURCE_EMPTY_ERR.getErrorCode());
        }
        for (String fileKey : multipartFileMap.keySet()) {
            List<MultipartFile> fileList = multipartRequest.getFiles(fileKey);
            Iterator<MultipartFile> fileIter = fileList.iterator();
            while (fileIter.hasNext()) {
                MultipartFile mediaFile = fileIter.next();
                String fileName = mediaFile.getOriginalFilename();
                InputStream fileStream = mediaFile.getInputStream();

                ByteArrayOutputStream streamForClone = cloneInputStream(fileStream);
                String fileMd5;
                String fileUrl;
                try {
                    //若是图片，真正类型必须是PNG
                    if (deviceMediaInfoSaveDTO.getType() == MediaTypeEnum.IMGAE.getType()){
                        InputStream checkStream = new ByteArrayInputStream(streamForClone.toByteArray());
                        try {
                            ImageInputStream iis = ImageIO.createImageInputStream(checkStream);
                            Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(iis);
                            while (imageReaders.hasNext()) {
                                ImageReader reader = imageReaders.next();
                                if (!StringHandlerUtil.compareStrIgnoreCaseWithOutEmpty(reader.getFormatName(),"png")){
                                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_IMAGE_TYPE_INVALID_ERR.getErrorCode());
                                }
                            }
                        } finally {
                            checkStream.close();
                        }
                    }
                    InputStream upLoadStream = new ByteArrayInputStream(streamForClone.toByteArray());
                    InputStream cloneStream = new ByteArrayInputStream(streamForClone.toByteArray());
                    try {
                        fileMd5 = DigestUtils.md5Hex(cloneStream);
                        fileUrl = this.uploadFile(upLoadStream, fileName);

                        //若是视频，需要获取其真正的分辨率
                        if (MediaTypeEnum.VIDEO.getType().equals(deviceMediaInfoSaveDTO.getType())) {
                            MessageVO analysisMessage = supVideoAnalysis(fileUrl);
                            if (analysisMessage != null) {
                                return analysisMessage;
                            }
                        }

                    } finally {
                        cloneStream.close();
                        upLoadStream.close();
                    }
                } finally {
                    streamForClone.close();
                }
                if (StringUtils.isBlank(fileUrl)) {
                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_UPLOAD_ERR.getErrorCode());
                }
                if (attacheFileUrls.length() <= 0) {
                    attacheFileUrls.append(fileUrl);
                    attacheFiles.append(fileName);
                    attacheFileMd5s.append(fileMd5);
                } else {
                    attacheFileUrls.append(",").append(fileUrl);
                    attacheFiles.append(",").append(fileName);
                    attacheFileMd5s.append(",").append(fileMd5);
                }
            }
        }
//        deviceMediaInfoSaveDTO.setAttacheFiles(attacheFiles.toString());
        deviceMediaInfoSaveDTO.setAttacheFileUrls(attacheFileUrls.toString());
        deviceMediaInfoSaveDTO.setAttacheFileMd5(attacheFileMd5s.toString());
        return null;

    }

    /**
     * <desc>
     *    更新上传多媒体资源到Http服务器.
     * </desc>
     *
     * @param httpServletRequest 请求到Http对象
     *   @param deviceMediaInfoUpdateDTO 待更新保存的多媒体信息对象
     * @return null 上传成功 or  MessageVO 上传失败的错误信息
     * @author Copy from LewisLouis by wangzhi
     * @createDate 2018-03-28
     */
    private MessageVO supUpLoadMediaFileForUpdate(HttpServletRequest httpServletRequest,
                                                  DeviceMediaInfoUpdateDTO deviceMediaInfoUpdateDTO,
                                                  DeviceMediaInfoGetVO deviceMediaInfoGetVO) throws IOException
    {

        List<DeviceMediaAttacheFileInfoVO> oldAttacheFiles = deviceMediaInfoGetVO.getAttacheFiles();

        MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) httpServletRequest;
        StringBuffer attacheFileUrls = new StringBuffer();
        StringBuffer attacheFiles = new StringBuffer();
        StringBuffer attacheFileMd5s = new StringBuffer();

        //第一步查看哪些附件没有变更
        for (DeviceMediaAttacheFileInfoVO oneOldDeviceMediaAttacheFileInfoVO:oldAttacheFiles){
            String attacheFileUrl = httpServletRequest.getParameter(oneOldDeviceMediaAttacheFileInfoVO.getAttacheFileUrl());
            if (StringHandlerUtil.compareStrIgnoreCaseWithOutEmpty(attacheFileUrl,oneOldDeviceMediaAttacheFileInfoVO.getAttacheFileUrl())){
                if (attacheFileUrls.length() <= 0) {
                    attacheFileUrls.append(oneOldDeviceMediaAttacheFileInfoVO.getAttacheFileUrl());
                    attacheFiles.append(oneOldDeviceMediaAttacheFileInfoVO.getFileName());
                    attacheFileMd5s.append(oneOldDeviceMediaAttacheFileInfoVO.getFileMd5());
                } else {
                    attacheFileUrls.append(",").append(oneOldDeviceMediaAttacheFileInfoVO.getAttacheFileUrl());
                    attacheFiles.append(",").append(oneOldDeviceMediaAttacheFileInfoVO.getFileName());
                    attacheFileMd5s.append(",").append(oneOldDeviceMediaAttacheFileInfoVO.getFileMd5());
                }

            }
        }

        //第二步查看新上传了哪些附件
        Map<String,MultipartFile> multipartFileMap = multipartRequest.getFileMap();
        if (multipartFileMap.isEmpty() && (attacheFileUrls.length() < 0)){
            return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_RESOURCE_EMPTY_ERR.getErrorCode());
        }
        for (String fileKey : multipartFileMap.keySet()) {
            List<MultipartFile> fileList = multipartRequest.getFiles(fileKey);
            Iterator<MultipartFile> fileIter = fileList.iterator();
            while (fileIter.hasNext()) {
                MultipartFile mediaFile = fileIter.next();
                String fileName = mediaFile.getOriginalFilename();
                InputStream fileStream = mediaFile.getInputStream();
                ByteArrayOutputStream streamForClone = cloneInputStream(fileStream);
                String fileMd5;
                String fileUrl;
                try {
                    if (deviceMediaInfoUpdateDTO.getType() == MediaTypeEnum.IMGAE.getType()){
                        InputStream checkStream = new ByteArrayInputStream(streamForClone.toByteArray());
                        try {
                            ImageInputStream iis = ImageIO.createImageInputStream(checkStream);
                            Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(iis);
                            while (imageReaders.hasNext()) {
                                ImageReader reader = imageReaders.next();
                                if (!StringHandlerUtil.compareStrIgnoreCaseWithOutEmpty(reader.getFormatName(),"png")){
                                    return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_IMAGE_TYPE_INVALID_ERR.getErrorCode());
                                }
                            }
                        } finally {
                            checkStream.close();
                        }
                    }
                    InputStream upLoadStream = new ByteArrayInputStream(streamForClone.toByteArray());
                    InputStream cloneStream = new ByteArrayInputStream(streamForClone.toByteArray());
                    try {
                        fileMd5 = DigestUtils.md5Hex(cloneStream);
                        DeviceMediaAttacheFileInfoVO deviceMediaAttacheFileInfoVO = getAttacheFileInfoByMD5(fileMd5,oldAttacheFiles);
                        if (null == deviceMediaAttacheFileInfoVO){
                            fileUrl = this.uploadFile(upLoadStream, fileName);
                            if (StringUtils.isBlank(fileUrl)) {
                                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_UPLOAD_ERR.getErrorCode());
                            }

                            //若是视频，需要获取其真正的分辨率
                            if (MediaTypeEnum.VIDEO.getType().equals(deviceMediaInfoUpdateDTO.getType())) {
                                MessageVO analysisMessage = supVideoAnalysis(fileUrl);
                                if (analysisMessage != null) {
                                    return analysisMessage;
                                }
                            }

                        } else {
                            fileUrl = deviceMediaAttacheFileInfoVO.getAttacheFileUrl();
                        }
                    } finally {
                        cloneStream.close();
                        upLoadStream.close();

                    }
                } finally {
                    streamForClone.close();
                }
                if (attacheFileUrls.length() <= 0) {
                    attacheFileUrls.append(fileUrl);
                    attacheFiles.append(fileName);
                    attacheFileMd5s.append(fileMd5);
                } else {
                    attacheFileUrls.append(",").append(fileUrl);
                    attacheFiles.append(",").append(fileName);
                    attacheFileMd5s.append(",").append(fileMd5);
                }
            }
        }
//        deviceMediaInfoUpdateDTO.setAttacheFiles(attacheFiles.toString());
        deviceMediaInfoUpdateDTO.setAttacheFileUrls(attacheFileUrls.toString());
        deviceMediaInfoUpdateDTO.setAttacheFileMd5(attacheFileMd5s.toString());
        return null;
    }

    /**
     * <desc>
     *     解析获取视频分辨率
     * </desc>
     *
     * @param fileUrl
     * @return
     * @author copy by wangzhi
     */
    private MessageVO supVideoAnalysis(String fileUrl) {
        //创建Xuggle容器
        IContainer container = IContainer.make();
        if (container.open(fileUrl, IContainer.Type.READ, null) < 0) {
            return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_TYPE_IS_NOT_VIDEO.getErrorCode());
        }
        int numStreams = container.getNumStreams();
        for (int i = 0; i < numStreams; i++) {
            IStreamCoder coder = container.getStream(i).getStreamCoder();
            //视频分辨率校验
            if (coder.getHeight() > 1080 || coder.getWidth() > 1920) {
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_VIDEO_RESOLUTION_RATIO_BEYOND.getErrorCode());
            }
            //视频格式校验
            if (ICodec.Type.CODEC_TYPE_VIDEO.equals(coder.getCodecType())
                    && PlatformConstants.MEDIA_PAGE_PLAY_VIDEO_SUPPORT_FORMAT.indexOf(String.valueOf(coder.getCodecID()).toUpperCase()) == -1) {
                return new MessageVO(PropertyErrorCodeEnum.EQUIP_MEDIA_VIDEO_FORMAT_NOT_SUPPORT.getErrorCode());
            }
        }
        return null;
    }

    /**
     * <desc>
     *     根据多媒体资源投放开始和结束时间推算多媒体资源的发布状态
     * </desc>
     *
     * @param putStartTime 多媒体资源投放开始时间
     * @param putEndTime 多媒体资源投放结束时间
     * @param date 用来比较的基准时间
     * @return 多媒体资源发布状态
     * @author wangzhi
     * @createDate 2018-04-09
     */
    public Integer calculateDeviceMediaPublishStatus(Date putStartTime,Date putEndTime,Date date){
        // publishStatus 发布状态0-已过期 1-已发布 2-未发布
        if (putStartTime.compareTo(date) > 0){
            // 投放开始时间大于date，未发布
            return 2;
        }
        if (putStartTime.compareTo(date) < 0 && putEndTime.compareTo(date) >0){
            // date在投放时间区间中，已发布
            return 1;
        }
        if (putEndTime.compareTo(date) < 0){
            // 投放结束时间小于date，已过期
            return 0;
        }
        return null;
    }

}


